package com.hzy.fivepalace.wx.service;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hzy.fivepalace.common.consts.RedisKeyConsts;
import com.hzy.fivepalace.common.exception.AppException;
import com.hzy.fivepalace.common.express.ExpressService;
import com.hzy.fivepalace.common.service.redis.RedisCache;
import com.hzy.fivepalace.common.type.*;
import com.hzy.fivepalace.common.util.*;
import com.hzy.fivepalace.db.dao.AppUserCommissionDetaiMapper;
import com.hzy.fivepalace.db.dao.DtsCommentMapper;
import com.hzy.fivepalace.db.dao.DtsOrderGoodsMapper;
import com.hzy.fivepalace.db.dao.DtsUserMapper;
import com.hzy.fivepalace.db.dao.ex.CommentMapperEx;
import com.hzy.fivepalace.db.dao.ex.DtsCouponUserMapperEx;
import com.hzy.fivepalace.db.dao.ex.DtsUserMapperEx;
import com.hzy.fivepalace.db.dao.ex.GoodsProductMapper;
import com.hzy.fivepalace.db.domain.*;
import com.hzy.fivepalace.db.handle.OrderHandler;
import com.hzy.fivepalace.db.handle.OrderOperator;
import com.hzy.fivepalace.db.service.*;
import com.hzy.fivepalace.db.vo.wx.WxApplyAfterSaleVo;
import com.hzy.fivepalace.db.vo.wx.WxGoodsCommentVo;
import com.hzy.fivepalace.db.vo.wx.WxUploadReturnLogisticsVo;
import jodd.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;


/**
 * 订单服务
 */
@Service
public class WxOrderService {

    private static final Logger logger = LoggerFactory.getLogger(WxOrderService.class);


    @Autowired
    private DtsOrderService orderService;

    @Autowired
    private DtsOrderGoodsService orderGoodsService;

    @Autowired
    private ExpressService expressService;

    @Resource
    private OrderHandler orderHandler;

    @Resource
    private Redisson redisson;

    @Autowired
    private WxBuyService wxBuyService;

    @Resource
    private DtsUserMapper userMapper;


    @Resource
    private AppUserCommissionDetaiMapper userCommissionDetaiMapper;

    @Resource
    private DtsUserMapperEx dtsUserMapperEx;

    @Resource
    private GoodsProductMapper goodsProductMapper;

    @Resource
    private DtsCouponUserMapperEx couponUserMapperEx;

    @Resource
    private DtsOrderGoodsMapper dtsOrderGoodsMapper;


    @Autowired
    private DtsVipConfigService dtsVipConfigService;

    @Resource
    private RedisCache redisCache;

    @Resource
    private DtsCommentMapper commentMapper;

    @Resource
    private CommentMapperEx commentMapperEx;

    @Autowired
    private DtsLogisticsService logisticsService;

    @Autowired
    private RefundService refundService;

    @Autowired
    private DtsSystemConfigService systemConfigService;
    @Resource
    private DtsGroupOpenListService groupOpenListService;
    @Resource
    private DtsGroupProductService groupProductService;

    @Autowired
    private PayService payService;

    private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

    private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(16, 16, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);

    /**
     * 获取各订单状态数量
     *
     * @param userId
     * @return
     */
    public Object getUserOrderCount(Integer userId) {
        //待支付数量
        Integer noPayCount = orderService.getUserOrderCount(userId, OrderStatusEnums.TYPE0.getType());
        //待发货数量
        Integer noDeliveryCount = orderService.getUserOrderCount(userId, OrderStatusEnums.TYPE1.getType());
        //待收货数量
        Integer takeCount = orderService.getUserOrderCount(userId, OrderStatusEnums.TYPE2.getType());
        //待评价数量
        Integer noEvaluationCount = orderService.getUserOrderCount(userId, OrderStatusEnums.TYPE3.getType());
        //售后中数量
        Integer afterSaleCount = orderService.getUserAfterSaleOrderCount(userId);

        Map<String, Integer> results = new HashMap<>();
        results.put("noPayCount", noPayCount);
        results.put("noDeliveryCount", noDeliveryCount);
        results.put("takeCount", takeCount);
        results.put("noEvaluationCount", noEvaluationCount);
        results.put("afterSaleCount", afterSaleCount);
        return ResponseUtil.ok(results);
    }

    /**
     * 订单列表
     *
     * @param page
     * @param size
     * @param userId
     * @param status 状态:为空就查所有,新增-1状态(查售后订单列表)
     * @return
     */
    public TableDataInfo getUserOrderList(Integer page, Integer size, Integer userId, Integer status) {
        if (null != status && status.intValue() != -1) {
            OrderStatusEnums orderStatusEnums = OrderStatusEnums.getEnum(status);
            if (null == orderStatusEnums) {
                return TableDataInfo.errorDataTable("查询状态错误");
            }
        }
        List<Map<String, Object>> orderVoList = new ArrayList<>();
        Page p = PageHelper.startPage(page, size, true);
        List<DtsOrderWithBLOBs> list = orderService.getUserOrderList(userId, status);
        list.forEach(item -> {
            DtsOrder order = JSONObject.parseObject(JSON.toJSONString(item), DtsOrder.class);
            Map<String, Object> orderVo = ObjectUtils.convertToMap(order);
            //删除不需要的字段
            orderVo.remove("userId");

            //支付方式
            orderVo.put("payName", null);

            //售后描述,前端判断该字段不为空就可以显示
            orderVo.put("afterSaleDescribe", item.getAfterSaleDescribe());

            //订单类型
            orderVo.put("orderType", item.getOrderType());
            //团购活动id
            orderVo.put("groupId", item.getGroupId());
            //拼团id
            orderVo.put("pinkId", item.getPinkId());

            //团购类型
            if(item.getOrderType() == 1){
                DtsGroupProduct groupProduct = groupProductService.getGroupProduct(item.getGroupId());
                orderVo.put("groupProduct", groupProduct);
            }

            //售后拒绝原因
            orderVo.put("afterSaleRefusedReason", item.getAfterSaleRefusedReason());

            if (order.getOrderStatus().intValue() != OrderStatusEnums.TYPE0.getType() && order.getOrderStatus().intValue() != OrderStatusEnums.TYPE6.getType()) {//已支付拼接支付方式
                if (order.getOrderPrice().compareTo(new BigDecimal("0.00")) <= 0) {//订单金额小于等于0就为免费订单
                    //支付方式
                    orderVo.put("payName", "免费订单");
                } else {
                    //支付方式
                    orderVo.put("payName", "微信支付");
                }
            }

            OrderStatusEnums orderStatusEnums = OrderStatusEnums.getEnum(order.getOrderStatus().intValue());
            //订单状态名称
            orderVo.put("orderStatusName", null == orderStatusEnums ? "未知状态" : orderStatusEnums.getName());
            //查询订单商品信息
            List<DtsOrderGoods> orderGoodsList = orderGoodsService.queryByOid(order.getId());
            orderVo.put("goodsList", orderGoodsList);
            //订单按钮操作
            orderVo.put("orderOperator", orderHandler.build(order));
            orderVoList.add(orderVo);
        });

        return TableDataInfo.getDataTable(orderVoList, p.getTotal());
    }

    /**
     * 删除订单
     *
     * @param body
     * @param userId
     * @return
     */
    public Object orderDel(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_orderDel_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (null == orderId || orderId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }

        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isDelete()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持删除");
        }

        DtsOrderWithBLOBs orderUpd = new DtsOrderWithBLOBs();
        orderUpd.setId(orderWithBLOBs.getId());
        orderUpd.setUpdateTime(LocalDateTime.now());
        orderUpd.setDeleted(true);
        orderService.updateById(orderUpd);
        lock.unlock();
        return ResponseUtil.ok("删除成功", null);
    }

    /**
     * 评价订单
     *
     * @param body
     * @param userId
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Object commentOrder(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_commentOrder_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (null == orderId || orderId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }

        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isEvaluation()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持评价");
        }
        JSONArray jsonArray = JacksonUtil.parseObject(body, "comment", JSONArray.class);
        if (null == jsonArray && jsonArray.size() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【comment】为空");
        }
        JSONArray newJsonArray = new JSONArray();
        //解析评价内容
        for (Object json : jsonArray) {
            JSONObject item = JSONObject.parseObject(JSON.toJSONString(json));
            Integer goodsId = item.getInteger("goodsId");
            String content = item.getString("content");
            JSONArray imgList = item.getJSONArray("img");
            Integer star = item.getInteger("star");
            if (null != item && null != goodsId && goodsId > 0 && (StringUtil.isNotBlank(content) || (null != imgList && imgList.size() > 0)) && null != star) {
                newJsonArray.add(item);
            }
        }
        if (newJsonArray.size() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数不完整");
        }

        for (Object json : newJsonArray) {
            JSONObject item = JSONObject.parseObject(JSON.toJSONString(json));
            Integer goodsId = item.getInteger("goodsId");
            String content = item.getString("content");
            Integer star = item.getInteger("star");
            JSONArray imgList = item.getJSONArray("img");
            List<Object> img = new ArrayList<>();
            //图片大于6张，就取前6张
            if (!CollectionUtils.isEmpty(imgList)) {
                if (imgList.size() > 6) {
                    for (int i = 0; i < 6; i++) {
                        img.add(imgList.get(i));
                    }
                } else {
                    img.addAll(imgList);
                }
            }
            DtsComment comment = new DtsComment();
            //初识化和赋值
            comment.setUpdateTime(LocalDateTime.now());
            comment.setAddTime(LocalDateTime.now());
            comment.setUserId(userId);
            comment.setValueId(goodsId);
            comment.setType(new Byte("0"));
            comment.setContent(content);
            comment.setStar(star.shortValue());
            comment.setDeleted(false);
            if (CollectionUtils.isEmpty(img)) {
                comment.setHasPicture(false);
            } else {
                comment.setHasPicture(true);
                comment.setPicUrls(img.toArray(new String[img.size()]));
            }
            commentMapper.insertSelective(comment);
        }
        //修改订单评价状态为已完成
        DtsOrderWithBLOBs dtsOrder = new DtsOrderWithBLOBs();
        dtsOrder.setId(orderId);
        dtsOrder.setComments((short) 0);
        dtsOrder.setUpdateTime(LocalDateTime.now());
        dtsOrder.setOrderStatus((short) OrderStatusEnums.TYPE4.getType());
        orderService.updateById(dtsOrder);
        lock.unlock();
        return ResponseUtil.ok("评价成功", null);
    }


    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void fenyong(DtsOrderWithBLOBs order) {
        //分佣实现

        DtsUser user = userMapper.selectByPrimaryKey(order.getUserId());//获取当前用户信息
        if (null == user) {
            return;
        }
        if (user.getRecodeUserId().equals(0)) {
            return;
        }
        //获取用户推荐人信息
        DtsUser reUser = userMapper.selectByPrimaryKey(user.getRecodeUserId());
        if (null == reUser) {
            return;
        }
        //获取推荐人会员等级
        VipTypeEnums reUserVipType = VipTypeEnums.getEnum(reUser.getVipType());
        if (null == reUserVipType) {
            return;
        }

        //获取推荐人的上级
        DtsUser toReUser = null;
//        VipTypeEnums toReUserVip = null;
        if (!reUser.getRecodeUserId().equals(0)) {
            toReUser = userMapper.selectByPrimaryKey(reUser.getRecodeUserId());
//            if (null != toReUser) {
//                toReUserVip = VipTypeEnums.getEnum(toReUser.getVipType());
//            }
        }


        //查询订单商品信息
        DtsOrderGoodsExample orderGoodsExample = new DtsOrderGoodsExample();
        orderGoodsExample.createCriteria().andOrderIdEqualTo(order.getId()).andDeletedEqualTo(false);
        List<DtsOrderGoods> goodsList = dtsOrderGoodsMapper.selectByExample(orderGoodsExample);

        for (DtsOrderGoods item : goodsList) {
            //获取商品嗨币比例配置
            DtsVipConfig scaleConfig = dtsVipConfigService.getGoodsExtendScale(reUserVipType.getId(), item.getProductId());
            if (null != scaleConfig) {
                BigDecimal goodsOneLevelExtendAmount = new BigDecimal(0);
                // order.getGoodsPrice().multiply(scaleConfig.getGoodsOneLevelExtendScale());
                //如果是 团购商品  分佣的 金额 需要按照 团购价格 来计算
                if(order.getOrderType() == 1){
                    goodsOneLevelExtendAmount = order.getOrderPrice().multiply(scaleConfig.getGoodsOneLevelExtendScale());
                }else{
                    goodsOneLevelExtendAmount = order.getGoodsPrice().multiply(scaleConfig.getGoodsOneLevelExtendScale());
                }


                if (goodsOneLevelExtendAmount.compareTo(new BigDecimal("0.01")) >= 0) {
                    AppUserCommissionDetai reUserCommissionDetai = new AppUserCommissionDetai();//推荐人嗨币明细对象
                    reUserCommissionDetai.setToUserId(order.getUserId());
                    reUserCommissionDetai.setUserId(reUser.getId());
                    reUserCommissionDetai.setAddTime(LocalDateTime.now());
                    reUserCommissionDetai.setAmount(goodsOneLevelExtendAmount);
                    reUserCommissionDetai.setOrderId(order.getId());
                    reUserCommissionDetai.setIssueStatus(CommissionIssueStatusTypeEnums.TYPE1.getId());
                    reUserCommissionDetai.setIssueTime(LocalDateTime.now());
                    reUserCommissionDetai.setParticularsMatter("购买产品");
                    reUserCommissionDetai.setCommissionType(CommissionIssueTypeEnums.TYPE1.getId());
                    reUserCommissionDetai.setScale(scaleConfig.getGoodsOneLevelExtendScale());
                    userCommissionDetaiMapper.insertSelective(reUserCommissionDetai);
                    dtsUserMapperEx.addUserCommission(reUser.getId(), goodsOneLevelExtendAmount);
                }

                if (reUserVipType.getId() != VipTypeEnums.TYPE1.getId() && null != toReUser) {///如果当前推荐人等级不为PLUS会员，而是其他的，并且推荐人有上一级,那就要给推荐人的推荐人分佣
                    BigDecimal goodsTwoLevelExtendAmount = new BigDecimal(0);
                    // order.getGoodsPrice().multiply(scaleConfig.getGoodsTwoLevelExtendScale());
                    if(order.getOrderType() == 1){
                        goodsTwoLevelExtendAmount = order.getOrderPrice().multiply(scaleConfig.getGoodsTwoLevelExtendScale());
                    }else{
                        goodsTwoLevelExtendAmount = order.getGoodsPrice().multiply(scaleConfig.getGoodsTwoLevelExtendScale());
                    }
                    if (goodsTwoLevelExtendAmount.compareTo(new BigDecimal("0.01")) >= 0) {
                        AppUserCommissionDetai toReUserCommissionDetai = new AppUserCommissionDetai();//推荐人的推荐人嗨币明细对象
                        toReUserCommissionDetai.setToUserId(reUser.getId());
                        toReUserCommissionDetai.setUserId(toReUser.getId());
                        toReUserCommissionDetai.setAddTime(LocalDateTime.now());
                        toReUserCommissionDetai.setAmount(goodsTwoLevelExtendAmount);
                        toReUserCommissionDetai.setOrderId(order.getId());
                        toReUserCommissionDetai.setIssueStatus(CommissionIssueStatusTypeEnums.TYPE1.getId());
                        toReUserCommissionDetai.setIssueTime(LocalDateTime.now());
                        toReUserCommissionDetai.setParticularsMatter("推广的用户购买产品");
                        toReUserCommissionDetai.setCommissionType(CommissionIssueTypeEnums.TYPE1.getId());
                        toReUserCommissionDetai.setScale(scaleConfig.getGoodsTwoLevelExtendScale());
                        userCommissionDetaiMapper.insertSelective(toReUserCommissionDetai);
                        dtsUserMapperEx.addUserCommission(toReUser.getId(), goodsTwoLevelExtendAmount);
                    }
                }
            }
        }

    }

    /**
     * 确认收货
     *
     * @param body
     * @param userId
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Object confirm(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_orderConfirm_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (null == orderId || orderId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        String takeImg = JacksonUtil.parseString(body, "takeImg");

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs || orderWithBLOBs.getIsByVip()) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }

        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isConfirm()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持收货");
        }
        DtsOrderWithBLOBs orderUpd = new DtsOrderWithBLOBs();
        orderUpd.setId(orderWithBLOBs.getId());
        orderUpd.setUpdateTime(LocalDateTime.now());
        //修改订单状态为待评价
        orderUpd.setOrderStatus((short) OrderStatusEnums.TYPE3.getType());
        orderUpd.setConfirmTime(LocalDateTime.now());
        orderUpd.setTakeImg(takeImg);
        orderService.updateById(orderUpd);
        if (orderWithBLOBs.getFreightType().intValue() == 0) {//配送方式为物流
            //删除自动收货缓存
            redisCache.deleteObject(RedisKeyConsts.AUTOMATIC_RECEIPT_GOODS_KEY + orderWithBLOBs.getOrderSn());
        }
        if (!orderWithBLOBs.getIsByVip()) {//购买商品
            fenyong(orderWithBLOBs);
        }

        lock.unlock();
        return ResponseUtil.ok("收货成功", null);
    }

    /**
     * 删除评价
     *
     * @param body
     * @param userId
     * @return
     */
    public Object delComments(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_delComments_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);
        Integer commentId = JacksonUtil.parseInteger(body, "commentId");
        if (null == commentId || commentId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【commentId】为空");
        }
        DtsComment comment = commentMapper.selectByPrimaryKey(commentId);
        if (null == comment || !comment.getUserId().equals(userId)) {
            lock.unlock();
            return ResponseUtil.fail("评价信息不存在");
        }
        comment.setDeleted(true);
        comment.setUpdateTime(LocalDateTime.now());
        commentMapper.updateByPrimaryKeySelective(comment);
        lock.unlock();
        return ResponseUtil.ok("删除成功", null);
    }

    /**
     * 支付订单
     *
     * @param body
     * @param userId
     * @return
     */
    public Object orderPay(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_orderPay_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);

        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (null == orderId || orderId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user) {
            lock.unlock();
            return ResponseUtil.unlogin();
        }

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isPay()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持支付");
        }
        //判断订单过期时间
        if (LocalDateTime.now().isAfter(orderWithBLOBs.getEndTime())) {
            lock.unlock();
            return ResponseUtil.badArgument("订单超时,无法支付");
        }
        Map<String, Object> data = new HashMap<>();
        try {
            //生成订单编号
            String orderNo = OrderUtils.generateOrderNo();
            orderWithBLOBs.setOutTradeNo(orderNo);
            //订单开始时间
            Calendar dateTime = DateUtils.convertLDTTOCalendar(orderWithBLOBs.getAddTime());
            WxPayMpOrderResult wxPayMpOrderResult =
                    wxBuyService.createWxAPPOrder(orderWithBLOBs.getIsByVip() ? "购买会员" : "购买商品",
                            orderWithBLOBs.getOutTradeNo(), orderWithBLOBs.getOrderPrice(), user.getWeixinOpenid(), dateTime);
            //去掉appid字段返回
            wxPayMpOrderResult.setAppId(null);
            data.put("wxPayInfo", wxPayMpOrderResult);
            //重新保存支付流水号
            orderService.updateById(orderWithBLOBs);
        } catch (Exception e) {
            logger.error("去支付订单失败：调用微信支付服务异常,userId:{},msg:{}", userId, e.getMessage());
            lock.unlock();
            throw new AppException("微信支付服务异常");
        }
        logger.info("【去支付订单请求结束】响应结果:{}", JSONObject.toJSONString(data));
        lock.unlock();
        return ResponseUtil.ok(data);
    }

    /**
     * 取消订单
     *
     * @param body
     * @param userId
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Object orderCancel(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_orderCancel_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);

        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (null == orderId || orderId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user) {
            lock.unlock();
            return ResponseUtil.unlogin();
        }

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isCancel()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持取消");
        }

        //使用的优惠券id
        Integer couponsId = orderWithBLOBs.getCouponsId();
        DtsOrderWithBLOBs orderUpd = new DtsOrderWithBLOBs();
        orderUpd.setId(orderWithBLOBs.getId());
        orderUpd.setCouponsId(0);
        orderUpd.setCouponPrice(new BigDecimal("0.00"));
        //订单状态改完已取消
        orderUpd.setOrderStatus((short) OrderStatusEnums.TYPE6.getType());
        orderUpd.setActualPrice(new BigDecimal("0.00"));
        //订单关闭时间为当前时间
        orderUpd.setEndTime(LocalDateTime.now());
        orderUpd.setUpdateTime(LocalDateTime.now());
        orderService.updateById(orderUpd);
        if (!orderWithBLOBs.getIsByVip()) {
            //查询订单商品信息
            DtsOrderGoodsExample orderGoodsExample = new DtsOrderGoodsExample();
            orderGoodsExample.createCriteria().andOrderIdEqualTo(orderWithBLOBs.getId()).andDeletedEqualTo(false);
            List<DtsOrderGoods> goodsList = dtsOrderGoodsMapper.selectByExample(orderGoodsExample);
            goodsList.forEach(item -> {
                //恢复货品库存
                goodsProductMapper.addStock(item.getProductId(), item.getNumber().shortValue());
            });
            if (null != couponsId && couponsId.intValue() > 0) {//使用了优惠券就更改优惠券为未使用
                couponUserMapperEx.setCouponsStatusIsNoUse(couponsId);
            }
        }

        //删除订单过期监听
        redisCache.deleteObject(RedisKeyConsts.ORDER_TIME_OUT_LISTENING_KEY + orderWithBLOBs.getOrderSn());
        lock.unlock();
        return ResponseUtil.ok("取消成功", null);
    }

    /**
     * 订单详情
     *
     * @param userId
     * @param orderId
     * @return
     */
    public Object orderDetails(Integer userId, Integer orderId) {
        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs) {
            return ResponseUtil.fail("订单不存在");
        }
        DtsOrder order = JSONObject.parseObject(JSON.toJSONString(orderWithBLOBs), DtsOrder.class);

        Map<String, Object> orderVo = ObjectUtils.convertToMap(order);
        //删除不需要的字段
        orderVo.remove("userId");

        //团购类型
        if(order.getOrderType() == 1){
            DtsGroupProduct groupProduct = groupProductService.getGroupProduct(order.getGroupId());
            orderVo.put("groupProduct", groupProduct);
        }


        //支付方式
        orderVo.put("payName", null);
        //售后描述,前端判断该字段不为空就可以显示
        orderVo.put("afterSaleDescribe", orderWithBLOBs.getAfterSaleDescribe());
        //售后拒绝原因
        orderVo.put("afterSaleRefusedReason", orderWithBLOBs.getAfterSaleRefusedReason());

        if (order.getOrderStatus().intValue() != OrderStatusEnums.TYPE0.getType() && order.getOrderStatus().intValue() != OrderStatusEnums.TYPE6.getType()) {//已支付拼接支付方式
            if (order.getOrderPrice().compareTo(new BigDecimal("0.00")) <= 0) {//订单金额小于等于0就为免费订单
                //支付方式
                orderVo.put("payName", "免费订单");
            } else {
                //支付方式
                orderVo.put("payName", "微信支付");
            }
        }
        OrderStatusEnums orderStatusEnums = OrderStatusEnums.getEnum(order.getOrderStatus().intValue());
        //订单状态名称
        orderVo.put("orderStatusName", null == orderStatusEnums ? "未知状态" : orderStatusEnums.getName());
        //查询订单商品信息
        List<DtsOrderGoods> orderGoodsList = orderGoodsService.queryByOid(order.getId());
        orderVo.put("goodsList", orderGoodsList);
        //订单按钮操作
        orderVo.put("orderOperator", orderHandler.build(order));

        if (order.getFreightType().intValue() == 0) {//物流配送就查，物流说明、不发货地区
            //获取物流说明
            orderVo.put("logisticsInstructions", logisticsService.getLogisticsInstructions());
            //获取不发货地区
            Callable<List<DtsNoDeliveryRegion>> noDeliveryRegionCallable = () -> logisticsService.getNoDeliveryRegionList(null);
            FutureTask<List<DtsNoDeliveryRegion>> noDeliveryRegionListTask = new FutureTask<>(noDeliveryRegionCallable);
            executorService.submit(noDeliveryRegionListTask);
            try {
                //不发货地区集合
                orderVo.put("noDeliveryRegionList", noDeliveryRegionListTask.get());
            } catch (Exception e) {
                logger.error("获取订单详情出错,订单id:{},msg:{}", order.getId(), e.getMessage());
                return ResponseUtil.fail("获取订单详情出错");
            }
        } else {
            orderVo.put("logisticsInstructions", null);
            orderVo.put("noDeliveryRegionList", new ArrayList<>());
        }

        return ResponseUtil.ok(orderVo);
    }


    /**
     * 获取退货地址,订单状态为11(待上传物流信息)用
     *
     * @return
     */
    public Object getReturnAdress() {
        return ResponseUtil.ok(systemConfigService.getReturnAdress());
    }

    /**
     * 查看物流
     *
     * @param userId
     * @param orderId
     * @return
     */
    public Object queryLogistics(Integer userId, Integer orderId) {
        // 订单信息
        DtsOrder order = orderService.findByIdAndUserId(orderId, userId);
        if (null == order || order.getIsByVip()) {
            return ResponseUtil.fail("获取物流信息失败,订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(order);
        if (!operator.isShowLogistics()) {
            return ResponseUtil.fail("获取物流信息失败,订单状态不支持查看");
        }
        return expressService.getExpressInfo(order.getShipChannel(), order.getShipSn(), order.getMobile());
    }

    /**
     * 查看退货物流
     *
     * @param userId
     * @param orderId
     * @return
     */
    public Object queryReturnLogistics(Integer userId, Integer orderId) {
        // 订单信息
        DtsOrder order = orderService.findByIdAndUserId(orderId, userId);
        if (null == order || order.getIsByVip()) {
            return ResponseUtil.fail("获取物流信息失败,订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(order);
        if (!operator.isShowReturnLogistics()) {
            return ResponseUtil.fail("获取物流信息失败,订单状态不支持查看");
        }
        return expressService.getExpressInfo(order.getReturnShipChannel(), order.getReturnShipSn(), order.getMobile());
    }

    /**
     * 用户评论列表
     *
     * @param userId
     * @param page
     * @param size
     * @return
     */
    public TableDataInfo getUserCommentList(Integer userId, Integer page, Integer size) {
        Page p = PageHelper.startPage(page, size);
        List<WxGoodsCommentVo> list = commentMapperEx.getUserCommentList(userId);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        } else {
            list.forEach(item -> {
                item.setCommentUserId(null);
            });
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }

    /**
     * 获取所有快递公司
     *
     * @return
     */
    public Object getAllShipChannelCode() {

        return ResponseUtil.ok(expressService.getAllShipChannel());
    }

    /**
     * 申请售后
     *
     * @param vo
     * @param userId
     * @return
     */
    public Object applyAfterSale(WxApplyAfterSaleVo vo, Integer userId) {
        RLock lock = redisson.getLock("wx_applyAfterSale_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);

        //校验入参
        if (null == vo.getOrderId() || vo.getOrderId().intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        if (null == vo.getApplyAfterSaleType()) {
            lock.unlock();
            return ResponseUtil.fail("请选择申请类型");
        }
        ApplyAfterSaleTypeEnums afterSaleTypeEnums = ApplyAfterSaleTypeEnums.getEnum(vo.getApplyAfterSaleType());
        if (null == afterSaleTypeEnums) {
            lock.unlock();
            return ResponseUtil.fail("参数【applyAfterSaleType】错误");
        }

        if (null == vo.getApplyAfterSaleTakeType()) {
            lock.unlock();
            return ResponseUtil.fail("请选择收货状态");
        }
        ApplyAfterSaleTakeTypeEnums takeTypeEnums = ApplyAfterSaleTakeTypeEnums.getEnum(vo.getApplyAfterSaleTakeType());
        if (null == takeTypeEnums) {
            lock.unlock();
            return ResponseUtil.fail("参数【applyAfterSaleTakeType】错误");
        }

        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user) {
            lock.unlock();
            return ResponseUtil.unlogin();
        }

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(vo.getOrderId(), userId);
        if (null == orderWithBLOBs || orderWithBLOBs.getIsByVip()) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isApplyAfterSale()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持申请售后");
        }
        String afterSaleDescribe = String.format("用户%s需要%s", takeTypeEnums.getName(), afterSaleTypeEnums.getName());
        if (StringUtils.isBlank(vo.getAfterSaleDescribe())) {
            vo.setAfterSaleDescribe(afterSaleDescribe);
        }
        //订单状态
        Short orderStatus = orderWithBLOBs.getOrderStatus();
        //订单状态名称
        String orderStatusName = OrderStatusEnums.getEnum(orderStatus.intValue()).getName();


        //修改订单状态
        DtsOrderWithBLOBs orderUpd = new DtsOrderWithBLOBs();
        orderUpd.setId(orderWithBLOBs.getId());
        //订单状态改完售后审核中
        orderUpd.setOrderStatus((short) OrderStatusEnums.TYPE8.getType());
        orderUpd.setUpdateTime(LocalDateTime.now());
        //申请售后时间
        orderUpd.setApplyAfterSaleTime(LocalDateTime.now());
        orderUpd.setAfterSaleDescribe(vo.getAfterSaleDescribe());
        orderUpd.setApplyAfterSaleTakeType(vo.getApplyAfterSaleTakeType());
        orderUpd.setApplyAfterSaleType(vo.getApplyAfterSaleType());
        orderUpd.setAfterSaleRefusedReason("");
        orderService.updateById(orderUpd);

        lock.unlock();
        return ResponseUtil.ok("申请已提交,请等待审核", null);
    }

    /**
     * 订单退款
     *
     * @param body
     * @param userId
     * @return
     */
    public Object orderRefund(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_orderRefund_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);

        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (null == orderId || orderId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user) {
            lock.unlock();
            return ResponseUtil.unlogin();
        }

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs || orderWithBLOBs.getIsByVip()) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isRefund()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持退款");
        }
        Object result = refundService.initiateWechatRefund(orderWithBLOBs, "订单未发货,用户主动退款", true);
        lock.unlock();
        return result;
    }

    /**
     * 取消售后申请
     *
     * @param body
     * @param userId
     * @return
     */
    public Object cancelAfterSale(String body, Integer userId) {
        RLock lock = redisson.getLock("wx_cancelAfterSale_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);

        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (null == orderId || orderId.intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user) {
            lock.unlock();
            return ResponseUtil.unlogin();
        }

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(orderId, userId);
        if (null == orderWithBLOBs || orderWithBLOBs.getIsByVip()) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isCancelAfterSale()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持取消");
        }

        //判断计算出未申请售后时的订单状态
        Integer oldOrderStatus = null;
        if (orderWithBLOBs.getComments().intValue() > 0 && null == orderWithBLOBs.getConfirmTime()) {//如果待评价订单商品数量大于0并且确认收货时间为空，那么一定是待收货状态
            oldOrderStatus = OrderStatusEnums.TYPE2.getType();
        } else if (orderWithBLOBs.getComments().intValue() > 0 && null != orderWithBLOBs.getConfirmTime()) {//如果待评价订单商品数量大于0并且确认收货时间不为空，那么一定是待评价状态
            oldOrderStatus = OrderStatusEnums.TYPE3.getType();
        } else if (orderWithBLOBs.getComments().intValue() < 1 && null != orderWithBLOBs.getConfirmTime()) {//如果待评价订单商品数量小于1并且确认收货时间不为空，那么一定是已完成状态
            oldOrderStatus = OrderStatusEnums.TYPE4.getType();
        } else {
            lock.unlock();
            return ResponseUtil.fail("计算未申请售后时的订单状态出错");
        }

        DtsOrderWithBLOBs orderUpd = new DtsOrderWithBLOBs();
        orderUpd.setId(orderWithBLOBs.getId());
        //修改订单状态为未申请售后时的订单状态
        orderUpd.setOrderStatus(oldOrderStatus.shortValue());
        orderUpd.setUpdateTime(LocalDateTime.now());
        orderUpd.setAfterSaleDescribe("用户已取消售后申请");
        orderService.updateById(orderUpd);

        lock.unlock();
        return ResponseUtil.ok("售后申请取消成功", null);
    }


    /**
     * 上传退货物流
     *
     * @param vo
     * @param userId
     * @return
     */
    public Object uploadReturnLogistics(WxUploadReturnLogisticsVo vo, Integer userId) {
        RLock lock = redisson.getLock("wx_uploadReturnLogistics_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);

        //校验入参
        if (null == vo.getOrderId() || vo.getOrderId().intValue() < 1) {
            lock.unlock();
            return ResponseUtil.fail("参数【orderId】为空");
        }
        if (StringUtils.isBlank(vo.getShipCode())) {
            lock.unlock();
            return ResponseUtil.fail("请选择快递公司");
        }
        if (StringUtils.isBlank(vo.getShipSn())) {
            lock.unlock();
            return ResponseUtil.fail("请填写快递单号");
        }
        //校验快递公司
        String vendorName = expressService.getVendorName(vo.getShipCode());
        if (StringUtils.isBlank(vendorName)) {
            lock.unlock();
            return ResponseUtil.fail("不受支持的快递公司");
        }


        DtsUser user = userMapper.selectByPrimaryKey(userId);
        if (null == user) {
            lock.unlock();
            return ResponseUtil.unlogin();
        }

        // 订单信息
        DtsOrderWithBLOBs orderWithBLOBs = orderService.findByIdAndUserId(vo.getOrderId(), userId);
        if (null == orderWithBLOBs || orderWithBLOBs.getIsByVip()) {
            lock.unlock();
            return ResponseUtil.fail("订单不存在");
        }
        //订单状态校验是否可以操作
        OrderOperator operator = orderHandler.build(orderWithBLOBs);
        if (!operator.isUploadReturnLogistics()) {
            lock.unlock();
            return ResponseUtil.fail("当前订单状态不支持上传");
        }

        DtsOrderWithBLOBs orderUpd = new DtsOrderWithBLOBs();
        orderUpd.setId(orderWithBLOBs.getId());
        //修改订单状态为未申请售后时的订单状态
        orderUpd.setOrderStatus((short) OrderStatusEnums.TYPE12.getType());
        orderUpd.setUpdateTime(LocalDateTime.now());
        orderUpd.setReturnShipChannel(vo.getShipCode());
        orderUpd.setReturnShipSn(vo.getShipSn());
        orderService.updateById(orderUpd);

        lock.unlock();
        return ResponseUtil.ok("上传成功,等待商家收货", null);
    }

}
